package com.ruoyi.system.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.xcx.AppUser;
import com.ruoyi.system.domain.xcx.DouyinApl;
import com.ruoyi.system.domain.xcx.Project;
import com.ruoyi.system.mapper.AppUserMapper;
import com.ruoyi.system.service.IAppUserService;
import com.ruoyi.system.util.WxPayV3Util;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 微信小程序用户Service业务层处理
 *
 * @author ruoyi
 * @date 2023-11-03
 */
@Service
public class AppUserServiceImpl implements IAppUserService
{
    @Autowired
    private AppUserMapper appUserMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询微信小程序用户
     *
     * @param id 微信小程序用户主键
     * @return 微信小程序用户
     */
    @Override
    public AppUser selectAppUserById(Long id)
    {
        return appUserMapper.selectAppUserById(id);
    }

    /**
     * 查询微信小程序用户列表
     *
     * @param appUser 微信小程序用户
     * @return 微信小程序用户
     */
    @Override
    public List<AppUser> selectAppUserList(AppUser appUser)
    {
        return appUserMapper.selectAppUserList(appUser);
    }

    /**
     * 新增微信小程序用户
     *
     * @param appUser 微信小程序用户
     * @return 结果
     */
    @Override
    public int insertAppUser(AppUser appUser)
    {
        appUser.setCreateTime(DateUtils.getNowDate());
        return appUserMapper.insertAppUser(appUser);
    }

    /**
     * 修改微信小程序用户
     *
     * @param appUser 微信小程序用户
     * @return 结果
     */
    @Override
    public int updateAppUser(AppUser appUser)
    {
        return appUserMapper.updateAppUser(appUser);
    }

    /**
     * 批量删除微信小程序用户
     *
     * @param ids 需要删除的微信小程序用户主键
     * @return 结果
     */
    @Override
    public int deleteAppUserByIds(Long[] ids)
    {
        return appUserMapper.deleteAppUserByIds(ids);
    }

    /**
     * 删除微信小程序用户信息
     *
     * @param id 微信小程序用户主键
     * @return 结果
     */
    @Override
    public int deleteAppUserById(Long id)
    {
        return appUserMapper.deleteAppUserById(id);
    }

    @Override
    public AppUser selectAppUserByOpenId(String openId) {
        return appUserMapper.selectAppUserByOpemId(openId);
    }

    @Override
    public String selectMerchant(String appId) {

        return appUserMapper.selectMerchant(appId);
    }

    @Override
    public List<Project> selectProjectList(Project project) {
        return appUserMapper.selectProjectList(project);
    }

    @Override
    public List<AppUser> selectAppUserByOpenIdList(AppUser appUser) {
        return appUserMapper.selectAppUserByOpenIdList(appUser);
    }

    /**
     * 用户充值
     * @param appUser
     * @param amount
     * @return
     */
    @Override
    @Transactional
    public AjaxResult addMoneyFromWechat(AppUser appUser, Long amount) throws Exception
    {
        JSONObject jsonpObject=new JSONObject();
        try {
            DouyinApl douyinApl=redisCache.getCacheObject(Constants.APPLI_CATION + appUser.getAplUuid());

            CloseableHttpClient httpClient =  HttpClients.createDefault();

            //下单接口请求参数
            ObjectMapper objectMapper = new ObjectMapper();
            String out_trade_no=appUser.getId()+DateUtils.dateTimeNow();
            System.out.println(out_trade_no);
            ObjectNode rootNode = objectMapper.createObjectNode();
            rootNode.put("appid", douyinApl.getXcxAppId())
                    .put("mchid", douyinApl.getMchid())
                    .put("description", "会员充值")
                    .put("notify_url", douyinApl.getXcxNotifyUrl())
                    .put("out_trade_no", out_trade_no);
            // 创建 amount 的 ObjectNode
            ObjectNode amountNode = objectMapper.createObjectNode();
            amountNode.put("total", amount); // amount 需要是 BigDecimal 类型
            amountNode.put("currency", "CNY");
            rootNode.set("amount", amountNode);
            rootNode.putObject("payer").put("openid", appUser.getOpenid());


            //构造请求认证标头
            long timestamp=System.currentTimeMillis() / 1000;
            String nonce_str=IdUtils.fastSimpleUUID();
            String url="https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
            String message=WxPayV3Util.getSignContent("POST",url,timestamp,nonce_str,rootNode.toString());
            String paySign=WxPayV3Util.signMessage(message,douyinApl.getXcxPaySecret());

            StringBuilder authorization = new StringBuilder();
            authorization.append("WECHATPAY2-SHA256-RSA2048 ");
            authorization.append("mchid=\"" + douyinApl.getMchid() + "\",");
            authorization.append("nonce_str=\"" + nonce_str + "\",");
            authorization.append("timestamp=\"" + timestamp + "\",");
            authorization.append("serial_no=\"" + douyinApl.getXcxSerialNumber() + "\",");
            authorization.append("signature=\"" +paySign + "\"");


            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("Accept", "application/json");
            httpPost.addHeader("Content-type","application/json; charset=utf-8");
            httpPost.addHeader("Authorization", String.valueOf(authorization));
            httpPost.setEntity(new StringEntity(JSONObject.toJSONString(rootNode), "UTF-8"));

            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String bodyAsString = EntityUtils.toString(response.getEntity());
                jsonpObject = JSONObject.parseObject(bodyAsString);
                jsonpObject.put("out_trade_no", out_trade_no);
                jsonpObject.put("timeStamp",timestamp);
                jsonpObject.put("nonceStr",nonce_str);
                jsonpObject.put("package","prepay_id="+jsonpObject.getString("prepay_id"));
                jsonpObject.put("paySign",WxPayV3Util.signMessage(WxPayV3Util.getSignContentResult(douyinApl.getXcxAppId(),timestamp,nonce_str,"prepay_id="+jsonpObject.getString("prepay_id")),douyinApl.getXcxPaySecret()));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return AjaxResult.success(jsonpObject);
    }

    @Override
    public AjaxResult closeOrder(AppUser appUser,String out_trade_no) throws Exception {
        DouyinApl douyinApl=redisCache.getCacheObject(Constants.APPLI_CATION + appUser.getAplUuid());
        CloseableHttpClient httpClient=HttpClients.createDefault();

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();

        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("mchid", douyinApl.getMchid());

        //构造请求认证标头
        long timestamp=System.currentTimeMillis() / 1000;
        String nonce_str=IdUtils.fastSimpleUUID();
        String url="https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"+out_trade_no+"/close";

        String message=WxPayV3Util.getSignContent("POST",url,timestamp,nonce_str,rootNode.toString());
        String paySign=WxPayV3Util.signMessage(message,douyinApl.getXcxPaySecret());

        StringBuilder authorization = new StringBuilder();
        authorization.append("WECHATPAY2-SHA256-RSA2048 ");
        authorization.append("mchid=\"" + douyinApl.getMchid() + "\",");
        authorization.append("nonce_str=\"" + nonce_str + "\",");
        authorization.append("timestamp=\"" + timestamp + "\",");
        authorization.append("serial_no=\"" + douyinApl.getXcxSerialNumber() + "\",");
        authorization.append("signature=\"" +paySign + "\"");


        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");
        httpPost.addHeader("Authorization", String.valueOf(authorization));
        httpPost.setEntity(new StringEntity(JSONObject.toJSONString(rootNode), "UTF-8"));


        CloseableHttpResponse response = httpClient.execute(httpPost);
        int statusCode=response.getStatusLine().getStatusCode();
        if (statusCode==204) {
            return AjaxResult.success(1);
        }
        return AjaxResult.error(EntityUtils.toString(response.getEntity()));
    }
}
